package com.uxsino.commons.logicSelector;

import javax.annotation.RegEx;
import java.util.Collection;
import java.util.Map;
import java.util.regex.Pattern;

public class GeneralPropOperators {

    public static class OpEq implements PropOperator {

        @Override
        public boolean accept(SelectorContext<?> context, Object object, java.lang.String valueString) {
            if (object == null)
                return false;

            if (Double.class.isAssignableFrom(object.getClass())) {
                try {
                    double d = Double.parseDouble(valueString);

                    return ((double) object) == d;
                } catch (NumberFormatException e) {
                }
            }
            return valueString.compareToIgnoreCase(object.toString()) == 0;
        }

    }

    public static class OpNe implements PropOperator {
        @Override
        public boolean accept(SelectorContext<?> context, Object object, java.lang.String valueString) {
            if (object == null)
                return false;

            if (Double.class.isAssignableFrom(object.getClass())) {
                try {
                    double d = Double.parseDouble(valueString);

                    return ((double) object) != d;
                } catch (NumberFormatException e) {
                }
            }
            return valueString.compareToIgnoreCase(object.toString()) != 0;
        }
    }

    public static class OpLt implements PropOperator {
        @Override
        public boolean accept(SelectorContext<?> context, Object object, java.lang.String valueString) {
            if (object == null)
                return false;

            if (Double.class.isAssignableFrom(object.getClass())) {
                try {
                    double d = Double.parseDouble(valueString);

                    return ((double) object) < d;
                } catch (NumberFormatException e) {
                }
            }
            return valueString.compareToIgnoreCase(object.toString()) < 0;
        }
    }

    public static class OpGt implements PropOperator {
        @Override
        public boolean accept(SelectorContext<?> context, Object object, java.lang.String valueString) {
            if (object == null)
                return false;

            if (Double.class.isAssignableFrom(object.getClass())) {
                try {
                    double d = Double.parseDouble(valueString);

                    return ((double) object) > d;
                } catch (NumberFormatException e) {
                }
            }
            return valueString.compareToIgnoreCase(object.toString()) > 0;
        }
    }

    public static class OpLe implements PropOperator {
        @Override
        public boolean accept(SelectorContext<?> context, Object object, java.lang.String valueString) {
            if (object == null)
                return false;

            if (Double.class.isAssignableFrom(object.getClass())) {
                try {
                    double d = Double.parseDouble(valueString);

                    return ((double) object) <= d;
                } catch (NumberFormatException e) {
                }
            }
            return valueString.compareToIgnoreCase(object.toString()) <= 0;
        }
    }

    public static class OpGe implements PropOperator {
        @Override
        public boolean accept(SelectorContext<?> context, Object object, java.lang.String valueString) {
            if (object == null)
                return false;

            if (Double.class.isAssignableFrom(object.getClass())) {
                try {
                    double d = Double.parseDouble(valueString);

                    return ((double) object) >= d;
                } catch (NumberFormatException e) {
                }
            }
            return valueString.compareToIgnoreCase(object.toString()) >= 0;
        }
    }

    public static class OpIn implements PropOperator {
        @Override
        public boolean accept(SelectorContext<?> context, Object object, java.lang.String valueString) {
            if (object == null)
                return false;

            String s = object.toString();
            for (String v : valueString.split(",")) {
                if (v.compareToIgnoreCase(s) == 0)
                    return true;
            }
            return false;
        }
    }

    public static class OpNotIn implements PropOperator {
        @Override
        public boolean accept(SelectorContext<?> context, Object object, java.lang.String valueString) {
            if (object == null)
                return false;

            String s = object.toString();
            for (String v : valueString.split(",")) {
                if (v.compareToIgnoreCase(s) == 0)
                    return false;
            }
            return true;
        }
    }

    public static class OpHas implements PropOperator {
        @Override
        public boolean accept(SelectorContext<?> context, Object object, java.lang.String valueString) {
            if (object == null)
                return false;

            if (object instanceof Map) {
                for (Object item : ((Map<?, ?>) object).keySet()) {
                    if (item != null) {
                        if (valueString.compareToIgnoreCase(item.toString()) == 0)
                            return true;
                    }
                }

            } else if (object instanceof Collection) {
                for (Object item : (Collection<?>) object) {
                    if (item != null) {
                        if (valueString.compareToIgnoreCase(item.toString()) == 0)
                            return true;
                    }
                }
            } else {
                for (String s : object.toString().split(",")) {
                    if (valueString.compareToIgnoreCase(s) == 0)
                        return true;
                }
            }
            return false;
        }
    }

    public static class OpExists implements PropOperator {
        @Override
        public boolean accept(SelectorContext<?> context, Object object, java.lang.String valueString) {
            return object != null;
        }
    }

    public static class OpReg implements PropOperator{
        @Override
        public boolean accept(SelectorContext<?> context, Object object, String valueString) {

            if ( object == null ) {
                return false;
            }
            String s = object.toString();
            Pattern pattern = Pattern.compile(valueString);
            return pattern.matcher(s).matches();
        }
    }

}
